package Export;

import java.awt.Desktop;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.util.ArrayList;

import javax.swing.JFileChooser;

import DataModel.Feature;
import DataModel.LociHolder;
import Utils.ClientHttpRequest;
import Viewer.Viewer;

/**
 * This class implements the Weblogo export. Also see:<br>
 * <a
 * href="http://weblogo.threeplusone.com/">http://weblogo.threeplusone.com/</a>
 * 
 * @author Stefan Lorenz<br>
 * <br>
 *         26.11.2012
 */
public class ExportWebLogo extends Thread {

	/**
	 * Viewer
	 */
	private Viewer viewer;

	/**
	 * Type of the feature sequences either 'amino acid', 'RNA' or 'DNA'
	 */
	private String event;

	/**
	 * Color scheme of the weblogo
	 */
	private String colorscheme;

	private String s;

	/**
	 * @param viewer
	 * @param event
	 */
	public ExportWebLogo(Viewer viewer, String event) {
		this.viewer = viewer;
		this.event = event;
		this.colorscheme = "color_auto";
		System.out.println("Running: Weblogo " + event);
		s = "";

		int smallestSize = Integer.MAX_VALUE;
		// looking for smallest selected sequence to have seq with same length
		for (int i = 0; i < viewer.getSelectedFeatureList().size(); i++) {
			if (viewer.getSelectedFeatureList().get(i).getStop() - viewer.getSelectedFeatureList().get(i).getStart() < smallestSize)
				smallestSize = viewer.getSelectedFeatureList().get(i).getStop() - viewer.getSelectedFeatureList().get(i).getStart();
		}

		for (int i = 0; i < viewer.getSelectedFeatureList().size(); i++) {
			Feature l = viewer.getSelectedFeatureList().get(i);

			// if the track of the feature ist anchored to an sequence
			// containing track use the sequence of this track
			ArrayList<String> seq = new ArrayList<String>();

			if (this.viewer.getLoadedTracks()[this.viewer.getTrackPositionLines(l.getTrackIndex()).getAnchor()].getTypeOfFile().equals("gbk")
					|| this.viewer.getLoadedTracks()[this.viewer.getTrackPositionLines(l.getTrackIndex()).getAnchor()].getTypeOfFile().equals("fasta")
					|| this.viewer.getLoadedTracks()[this.viewer.getTrackPositionLines(l.getTrackIndex()).getAnchor()].getTypeOfFile().equals("embl")) {
				seq = ((LociHolder) this.viewer.getLoadedTracks()[this.viewer.getTrackPositionLines(l.getTrackIndex()).getAnchor()]).getSplicedSequenceFromTo(
						((LociHolder) this.viewer.getLoadedTracks()[this.viewer.getTrackPositionLines(l.getTrackIndex()).getAnchor()]).getListOfLoci().get(0).getLocusName(), l.getListOfPositions());
			}

			else if (!(this.viewer.getLoadedTracks()[l.getTrackIndex()].getTypeOfFile().equals("gbk") || this.viewer.getLoadedTracks()[l.getTrackIndex()].getTypeOfFile().equals("embl") || this.viewer.getLoadedTracks()[l.getTrackIndex()]
					.getTypeOfFile().equals("fasta"))) {
				System.err.println("No Sequence in track " + l.getTrackIndex() + " for " + l.getName() + " " + l.getStart() + ".." + l.getStop());
				continue;
			}

			String sequence = "";
			for (int j = 0; j < seq.size(); j++) {
				sequence += seq.get(j).toUpperCase();
			}
			sequence = sequence.substring(0, smallestSize + 1);

			// DNA
			if (this.event.equals("DNA")) {
				if (l.getStrand().equals("+"))
					s += ">\n" + sequence + "\n";
				else {
					StringBuilder reverseSeq = new StringBuilder();
					for (int x = 0; x < sequence.length(); x++) {
						reverseSeq.append(this.viewer.getComplementOfBase(sequence.charAt(x)));
					}
					reverseSeq.reverse();
					s += ">\n" + reverseSeq.toString() + "\n";
				}
				this.colorscheme = "color_classic";
			}
			// RNA
			else if (this.event.equals("RNA")) {
				s += ">\n" + sequence.replace('T', 'U') + "\n";
			}
			// Amino Acid
			else if (this.event.equals("AA")) {
				this.colorscheme = "color_chemistry";
				StringBuilder sb = new StringBuilder();
				StringBuilder reverseSeq = new StringBuilder();
				for (int x = 0; x < sequence.length(); x++) {
					reverseSeq.append(this.viewer.getComplementOfBase(sequence.charAt(x)));
				}
				reverseSeq.reverse();

				for (int k = 0; k < sequence.length() - 2; k += 3) {
					if (l.getStrand().equals("+"))
						sb.append(viewer.getAminoAcidTable().get(sequence.substring(k, k + 3)));
					else {
						sb.append(viewer.getAminoAcidTable().get(reverseSeq.substring(k, k + 3)));
					}
				}
				s += ">\n" + sb.toString() + "\n";
			}
		}
		// WebLogo3
		start();
	}

	@Override
	public void run() {
		super.run();
		try {
			File output;
			if (this.viewer.getFileChooser().showSaveDialog(this.viewer) == JFileChooser.APPROVE_OPTION) {
				output = this.viewer.getFileChooser().getSelectedFile();
				if (!output.getAbsolutePath().endsWith(".pdf"))
					output = new File(output + ".pdf");

				InputStream serverInput1 = ClientHttpRequest.post(new java.net.URL("http://weblogo.threeplusone.com/create.cgi"), new Object[] { "format", "pdf", "sequences_file", s, "stacks_per_line", "40", "ignore_lower_case", "true",
						"first_index", "1", "logo_start", "", "logo_end", "", "percentCG", "", "color_scheme", colorscheme, "show_errorbars", "true", "scale_width", "true", "logo_title", "", "logo_label", "", "yaxis_scale", "auto",
						"yaxis_tic_interval", "1", "color_scheme", "color_auto", "show_xaxis", "true", "show_yaxis", "true" });

				BufferedReader in = new BufferedReader(new InputStreamReader(serverInput1));

				FileOutputStream out = new FileOutputStream(output);
				final int BUFFER_SIZE = 1 << 10 << 3; // 8KiB buffer
				byte[] buffer = new byte[BUFFER_SIZE];
				int bytesRead = -1;

				while ((bytesRead = serverInput1.read(buffer)) > -1) {
					out.write(buffer, 0, bytesRead);
				}
				in.close();
				out.flush();
				out.close();
				if (Desktop.getDesktop().isSupported(Desktop.Action.OPEN))
					Desktop.getDesktop().open(output);
			}

		} catch (IOException e) {

		}
	}

}
